<?php

class Autoevaluacion_Model_DetalleLista extends Model_Cna {
	
	private $seccionesTable;
	private $elementosTable;
	
	public function __construct() {
		parent::__construct();
		$this->seccionesTable = new Autoevaluacion_Model_DbTable_Secciones();
		$this->elementosTable = new Autoevaluacion_Model_DbTable_ElementosLista();
	}
	
	public function asignarPonderaciones(array $param) {
	    for ($i = 0; $i < count($param["codelementolista"]); $i++) {
	        $suma = $param["pesodoc"][$i] + $param["pesoind"][$i] + $param["pesoenc"][$i];
	        if(100 != $suma) {
	            throw new Zend_Exception("Los pesos deben sumar 100 para la caracteristica ".($i+1));
	        }
	        $suma = $param["pesodir"][$i] + $param["pesoprof"][$i] + $param["pesoest"][$i] + $param["pesoegre"][$i] + $param["pesoadm"][$i] + $param["pesosec"][$i];
	        if(100 != $suma) {
	            throw new Zend_Exception("Los pesos desagregados de la encuesta deben sumar 100 para la caracteristica ".($i+1));
	        }
	    }
	    $this->elementosTable->getAdapter()->beginTransaction();
	    try {
	        for ($i = 0; $i < count($param["codelementolista"]); $i++) {
	            $where = "codelementolista={$param["codelementolista"][$i]} ";
	            $datos = array();
	            $datos["pesodoc"] = $param["pesodoc"][$i];
	            $datos["pesoind"] = $param["pesoind"][$i];
	            $datos["pesoenc"] = $param["pesoenc"][$i];
	            $datos["pesodir"] = $param["pesodir"][$i];
	            $datos["pesoprof"] = $param["pesoprof"][$i];
	            $datos["pesoest"] = $param["pesoest"][$i];
	            $datos["pesoegre"] = $param["pesoegre"][$i];
	            $datos["pesoadm"] = $param["pesoadm"][$i];
	            $datos["pesosec"] = $param["pesosec"][$i];
		        $this->elementosTable->update($datos, $where);
	        }
	        $this->elementosTable->getAdapter()->commit();
        	
	    } catch (Exception $e) {
	        $this->elementosTable->getAdapter()->rollBack();
	        throw $e;
	    }
	    
	}
	
	public function getSecciones($codlista, $withEscalas=false) {
		$result = $this->seccionesTable->getSecciones($codlista);
		$escalasTable = new Listas_Model_DbTable_Escalas();
	    for($i=0, $total = count($result); $i < $total; $i++) {
		    $result[$i]["elementos"] = $this->elementosTable->getElementosAsignados($result[$i]["codseccionlista"]);
			if($withEscalas && count($result[$i]["elementos"]) >0) {
			    for($j=0, $total_j=count($result[$i]["elementos"]); $j < $total_j; $j++ ) {
			        $result[$i]["elementos"][$j]["escalas"] = $escalasTable->getEscalasByElemento($result[$i]["elementos"][$j]["codelementolista"]);
			        //Zend_Debug::dump($result[$i]["elementos"][$j]["escalas"]);
			    }
			}
		}
//		Zend_Debug::dump($registros);
		return $result;
	}
	
    public function getSeccion($codseccionlista, $withElementos=false) {
		$result = $this->seccionesTable->find($codseccionlista)->current()->toArray();
		if($withElementos) {
	        $result["elementos"] = $this->elementosTable->getElementosAsignados($result["codseccionlista"]);
		}
		return $result;
	}
	
	/**
	 * Elimina una seccion de la lista
	 * @param integer $codseccionlista
	 */
    public function eliminarSeccion($codseccionlista) {
		$row = $this->seccionesTable->find($codseccionlista)->current();
		$codlista = $row->codlista;
		$row->delete();
		$this->seccionesTable->resetOrden($codlista);
	}
	
	/**
	 * Guardar los datos de una seccion para una lista
	 * @param array $datos
	 * @return integer la llave primaria de la sección creada o modificada
	 */
	public function guardarSeccion(array $datos) {
	    if(!empty($datos["codseccionlista"])) {
			return $this->seccionesTable->find($datos["codseccionlista"])->current()->setFromArray($datos)->save();
		} else {
		    unset($datos["codseccionlista"]);
		    $orden = $this->seccionesTable->nextOrden($datos["codlista"]);
		    $row = $this->seccionesTable->createRow();
		    $row->setFromArray($datos);
		    $row->orden = $orden;
			return $row->save();
		}
	}
	
	/**
	 * Guardar los datos de un elemento/pregunta para una sección de lista en el banco de preguntas
	 * @param array $datos
	 * @param array $opciones
	 * @param array $pesos
	 * @param array $codigos
	 * @return integer la llave primaria de la pregunta creada o modificada
	 */
	public function guardarElementoBanco(array $datos, array $opciones, array $pesos, array $codigos) {
	    $this->elementosTable->getAdapter()->beginTransaction();
	    try {
            $datos = $this->forceEmptyAsNull($datos);
            $modificando = false;
            if(!empty($datos["codelementolista"])) {
                $modificando = true;
                $rowanterior = $this->elementosTable->find($datos["codelementolista"])->current();
                $tipopregunta_anterior = $rowanterior->tipopregunta;
        		$codelementolista = $rowanterior->setFromArray($datos)->save();
        	} else {
        	    unset($datos["codelementolista"]);
        	    $codelementolista = $this->elementosTable->createRow($datos)->save();
        	}
        	
        	if(isset($datos["tipopregunta"])) {
    	        $escalasService = new Listas_Model_Escalas();
    	        $escalas_eliminadas = false;
            	//primero vemos si cambio el tipo para eliminar las escalas y crearlas desde cero
            	if($modificando && (($tipopregunta_anterior=="SINO" && ($datos["tipopregunta"]=="MU" || $datos["tipopregunta"]=="MM"))
            	    || ($datos["tipopregunta"]=="SINO" && ($tipopregunta_anterior=="MU" || $tipopregunta_anterior=="MM"))) ) {
            	    $escalasService->deleteEscalasByElemento($codelementolista);
            	    $escalas_eliminadas = true;
            	}
            	
            	//Ahora creamos las escalas para el elemento
                $datos_escala = array();
                $datos_escala["codelementolista"] = $codelementolista;
                if($datos["tipopregunta"]=="MU" || $datos["tipopregunta"]=="MM") {
    	            if(!is_array($opciones) || !is_array($pesos) || count($opciones)!=count($pesos)) {
    	                throw new Exception("Las opciones de respuesta no corresponden con los pesos");
    	            }
    	            if(array_sum($pesos) != 100) {
    	                throw new Exception("La suma de todos los pesos, debe ser 100");
    	            }
    	            if($datos["tipopregunta"]=="MU" && !in_array(100, $pesos)) {
    	                throw new Exception("En la pregunta de tipo selección única, solo una opción debe tener peso 100, las demás deben tener 0");
    	            }
    	            if($modificando) {
    	                $escalas = $escalasService->getEscalasByElemento($codelementolista);
    	                if(is_array($escalas)) {
    	                    foreach($escalas as $index => $item) {
    	                        if(!in_array($item["codescala"], $codigos)) {
    	                            $escalasService->eliminarEscala($item["codescala"]);
    	                        }
    	                    }
    	                }
    	            }
    	            
    	            for($i=0; $i<count($opciones); $i++) {
                		$datos_escala["nombre"] = trim($opciones[$i]);
                		$datos_escala["peso"] = $pesos[$i];
                		$datos_escala["codescala"] = $codigos[$i];
        	            $escalasService->guardarEscala($datos_escala);
    	            }
    	        } else {
    	            if(!$modificando || $escalas_eliminadas) {
        	            //se crean las opciones SI y NO por defecto si no se esta modificando
        	            //si se esta modificando y sigue siendo de tipo SINO, ya las debe tener
        	            $datos_escala["nombre"] = "Si";
                		$datos_escala["peso"] = 100;
        	            $escalasService->guardarEscala($datos_escala);
        	            
        	            $datos_escala["nombre"] = "No";
                		$datos_escala["peso"] = 0;
        	            $escalasService->guardarEscala($datos_escala);
    	            }
    	        }
        	}//cierre de if(isset($datos["tipopregunta"]))
        	
        	$this->elementosTable->getAdapter()->commit();
        	return $codelementolista;
	    } catch (Exception $e) {
	        $this->elementosTable->getAdapter()->rollBack();
	        throw $e;
	    }
	}
	
	/**
	 * Obtiene todos los elementos del banco que pertenezcan a un tipo
	 * de lista especifico, y que no se encuentren asignados previamente a una lista
	 * @param string $tipolista el tipo de la lista de la que se desean obtener los elementos
	 * @param integer $codlista código de la lista para filtrar los elementos que se obtienen
	 * @return array
	 */
	public function getElementosBanco($tipolista, $codlista, $codinstitucion=NULL) {
		$registros = $this->elementosTable->getElementos($tipolista, $codlista, $codinstitucion);
		$listasTable = new Autoevaluacion_Model_DbTable_Listas();
		for($i=0, $total = count($registros); $i < $total; $i++) {
		    $registros[$i]["listas"] = $listasTable->getListasAsignadasElemento($registros[$i]["codelementolista"]);
			
		}
//		Zend_Debug::dump($registros);
		return $registros;
	}
	
	/**
	 * Obtiene todos los elementos asignados a una seccion
	 * @param integer $codseccionlista código de la seccion para filtrar los elementos que se obtienen
	 * @param boolean $withListasAsignadas indica si se deben incluir en los resultados las listas a las que se encuentra
	 * 										asignado cada elemento
	 * @param boolean $withCaracteristicasAsociadasSeccion indica si se deben incluir las caracteristicas asociadas a la pregunta
	 * @return array
	 */
	public function getElementosAsignados($codseccionlista, $withListasAsignadas=true, $withCaracteristicasAsociadasSeccion=false) {
		$registros = $this->elementosTable->getElementosAsignados($codseccionlista);
//		if($withListasAsignadas) {
//    		$listasTable = new Autoevaluacion_Model_DbTable_Listas();
//    		for($i=0, $total = count($registros); $i < $total; $i++) {
//    		    $registros[$i]["listas"] = $listasTable->getListasAsignadasElemento($registros[$i]["codelementolista"]);
//
//    		}
//		}
        if(!empty($withCaracteristicasAsociadasSeccion)) {
            $elementoCaracteristicas = new Autoevaluacion_Model_DbTable_ElementoCaracteristicas();
            for($i=0, $total = count($registros); $i < $total; $i++) {
                $registros[$i]["caracteristicas"] = $elementoCaracteristicas->getCaracteristicasAsignadas($registros[$i]["codelementolista"], $codseccionlista);
            }
        }
		//Zend_Debug::dump($registros);
		return $registros;
	}
	
	/**
	 * Actualiza el texto de un elemento, se utiliza en pantallas donde ya estan asignadas a listas
	 * @param int $codelementolista
	 * @param string $texto
	 */
	public function updateTextoElemento($codelementolista, $texto) {
	    $this->elementosTable->find($codelementolista)->current()->setFromArray(array("texto"=>$texto))->save();
	}
	
	/**
	 * Obtiene un elemento, opcionalmente con las escalas (pregunmtas con sus opciones de respuesta)
	 * @param int $codelementolista
	 * @param boolean $withEscalas
	 */
	public function getElemento($codelementolista, $withEscalas=false) {
		$registros = $this->elementosTable->find($codelementolista)->current()->toArray();
		if($withEscalas) {
		    $escalasTable = new Listas_Model_DbTable_Escalas();
		    $registros["escalas"] = $escalasTable->getEscalasByElemento($codelementolista);
		}
		return $registros;
	}
	
    public function eliminarElemento($codelementolista) {
		return $this->elementosTable->find($codelementolista)->current()->delete();
	}
	
    public function asignarElementoSeccion($codelementolista, $codseccion) {
        $this->elementosTable->asignarElementoSeccion($codelementolista, $codseccion);
		//return $this->elementosTable->find($codelementolista)->current()->delete();
	}
	
	/**
	 * Asignar un conjunto de elementos/preguntas a una sección de una lista
	 * @param array $elementos códigos de los elementos a asignar
	 * @param integer $codseccion código de la sección a la que se deben asignar los elementos
	 */
	public function asignarArrayElementoSeccion(array $elementos, $codseccion) {
		$this->elementosTable->getAdapter()->beginTransaction();
		try {
			foreach ($elementos as $codelementolista) {
				$this->elementosTable->asignarElementoSeccion($codelementolista, $codseccion);
			}
		    $this->elementosTable->getAdapter()->commit();
		} catch (Exception $e) {
		    $this->elementosTable->getAdapter()->rollBack();
		    throw $e;
		}
	}
	
	/**
	 * Remover un conjunto de elementos/preguntas de una sección de una lista
	 * @param array $elementos códigos de los elementos a remover
	 * @param integer $codseccion código de la sección de la que se deben remover los elementos
	 */
	public function removerArrayElementoSeccion(array $elementos, $codseccion) {
		$this->elementosTable->getAdapter()->beginTransaction();
		try {
			foreach ($elementos as $codelementolista) {
				$this->elementosTable->removerElementoSeccion($codelementolista, $codseccion);
			}
			$this->elementosTable->resetOrden($codseccion);
		    $this->elementosTable->getAdapter()->commit();
		} catch (Exception $e) {
		    $this->elementosTable->getAdapter()->rollBack();
		    throw $e;
		}
	}
	
/**
	 * Asignar un conjunto de caracteristicas (elementos) a  una pregunta
	 * @param array $elementos códigos de los elementos a asignar
	 * @param integer $codseccion código de la sección a la que se deben asignar los elementos
	 */
	public function asignarArrayCaracteristicas(array $caracteristicas, $codelementolista, $codseccion) {
	    $elementoCaracteristicas = new Autoevaluacion_Model_DbTable_ElementoCaracteristicas();
	    $elementoCaracteristicas->getAdapter()->beginTransaction();
	    
		try {
		    $elementoCaracteristicas->deleteAsignaciones($codelementolista, $codseccion);
		    
			foreach ($caracteristicas as $codcaracteristica) {
			    $datos = array();
                $datos["codelementolista"] = $codelementolista;
                $datos["codseccionlista"] = $codseccion;
                $datos["codcaracteristica"] = $codcaracteristica;
                $elementoCaracteristicas->insert($datos);
				//$elementoCaracteristicas->asignarCaracteristica($codelementolista, $codseccion, $codcaracteristica);
			}
		    $elementoCaracteristicas->getAdapter()->commit();
		    
		} catch (Exception $e) {
		    $elementoCaracteristicas->getAdapter()->rollBack();
		    throw $e;
		}
	}
	
	public function getCaracteristicasAsignadas($codelementolista, $codseccion) {
	    $elementoCaracteristicas = new Autoevaluacion_Model_DbTable_ElementoCaracteristicas();
	    return $elementoCaracteristicas->getCaracteristicasAsignadas($codelementolista, $codseccion);
	}
	
}//fin de la clase